package com.syncomponents.client.jms;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.syncomponents.client.MessageHelper;

import commonj.sdo.DataObject;


/**
 * jms接收者抽象类，实现doRecieve做真正的业务处理，必须指定 getClazzType
 * 
 * @author sunkey
 * @date Mar 27, 2014
 */
public abstract class AbstractJmsReceiver<T> implements IJmsReceiver<T> {
    
    protected final static Logger logger = LoggerFactory.getLogger(AbstractJmsReceiver.class);

    @SuppressWarnings("unchecked")
    @Override
    public Object recieve(Message message) throws JMSException {
        Class<T> clazz = getClazzType();
        if(null == clazz){
            throw new IllegalArgumentException("getClazzType return null");
        }
        Object resultObj = null;
            if (message instanceof TextMessage) {
                TextMessage textMessage = (TextMessage) message;
                try {
                    if (clazz.equals(DataObject.class)) {
                        resultObj = MessageHelper.toDataObject(textMessage);
                    } else {
                        resultObj = MessageHelper.toString(textMessage);
                    }
                } catch (ClassNotFoundException e) {
                    logger.error(e.getMessage(), e);
                    throw new JMSException(e.getMessage());
                }
            } else {
                ObjectMessage objectMessage = (ObjectMessage) message;
                resultObj = objectMessage.getObject();
            }
            
           return doRecieve((T)resultObj);
    }
    
    @Override
    public void reply(Session session, Destination replyTo, Object obj) throws JMSException {
        // do nothing
    }

    /**
     * 可做业务处理
     * @param obj 消息內容
     * @return 不需要回复返回空
     */
    public abstract Object doRecieve(T obj);
    
    /**
     * 消息处理的类型，eg: String, DataObject
     * @return
     */
    public abstract Class<T> getClazzType();

}
